#pragma once

#include<iostream>
#include<string>
#include<cstring>
#include<assert.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<sys/stat.h>
#include<fcntl.h>
#include "log.hpp"

using namespace std;

#define SHM_SIZE 4096 //shmget参数:定义shm的大小，最好是页(PAGE，4096，4kb)的整数倍
#define PROJ_ID 0x44//ftok参数:值可随意，the least significant 8 bits of proj_id (which must be nonzero)
#define PATH_NAME "/home/wj"//路径正确即可。



/////////////////
//用于让共享内存达到访问控制的一些设置：借助管道实现

#define FIFO_NAME "./fifo" //将名命管道创建在当前目录下，名称为fifo

#define READ O_RDONLY //以读的方式打开管道文件
#define WRITE O_WRONLY //以写的方式打开管道文件


//类：用于让进程运行、关闭时，自动创建、销毁管道文件
class Init
{
public:
    Init()//默认构造
    {
        umask(0);
        int fifoid = mkfifo(FIFO_NAME,0666);
        assert(fifoid != -1);
        (void)fifoid;
        Log("FIFO pipe created!", Notice);
    }

    ~Init()//默认析构
    {
        unlink(FIFO_NAME);
        Log("remove FIFO pipe!", Notice);
    }
};

//函数：主要目的是为读写两端以不同方式打开管道文件
int OpenFIFO(std::string pathname, int flags)
{
    int fd = open(pathname.c_str(),flags);
    assert(fd > 0);
    (void)fd;
    return fd;
}


//函数：等待。让读端处于等待中，直到从管道文件中接受到指令。
void Wait(int fd)//此处fd是管道文件
{
    uint32_t command = 0;//指令：对于输入内容不重要，只是为了控制
    ssize_t n = read(fd, &command, sizeof(uint32_t));
    assert(n == sizeof(uint32_t));
    (void)n;
}


//函数：唤醒。当写端数据输入完成后，输入指令唤醒读端。
void Signal(int fd)//此处fd是管道文件
{
    uint32_t command = 0;
    ssize_t n = write(fd, &command, sizeof(uint32_t));
    assert(n == sizeof(uint32_t));
    (void)n;
}


//函数：关闭管道文件.
void closeFIFO(int fd)
{
    close(fd);
}
/////////////////
